﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.IO;
using System.Text.RegularExpressions;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;
using System.Linq;

namespace TARADesktopDoctor
{
    public partial class EditPatient
    {
        tara_wcf.ItaraServiceClient svc = new tara_wcf.ItaraServiceClient();
        tara_wcf.patient patientDetail = new tara_wcf.patient();
        public EditPatient(tara_wcf.patient p)
        {
            this.InitializeComponent();
            patientDetail = p;
            //cbxCountry1.Items.Add("Singapore");
            grid_loading.Visibility = Visibility.Collapsed;
            tbxAddress3.Text = p.Address1;
            tbxEmail1.Text = p.Email;
            tbxFirstName1.Text = p.FirstName;
            tbxIDNum1.Text = p.Nric;
            tbxLastName1.Text = p.LastName;
            tbxMobNum1.Text = p.ContactNumMob;
            tbxPostalCode.Text = p.Postcode;
            tbxTelNum1.Text = p.ContactNumHome;
            if (p.Gender == "Male")
            {
                rbtnMale1.IsChecked = true;
            }
            else if (p.Gender == "Female")
            {
                rbtnFemale1.IsChecked = true;
            }
            if (p.ImageByte != null)
            {
                imgProfilePicture1.Source = LoadImage(p.ImageByte);
            }
            dtpAdmissionDate.Text = p.AdminDate.ToString("MMMM dd, yyyy");
            dtpBirthDate1.Text = p.DateOfBirth.ToString("MMMM dd, yyyy");
            // Insert code required on object creation below this point.
        }

        bool fillFile = false;
        string imgName = "";
        private void btnUpdate_Click(object sender, RoutedEventArgs e)
        {

            #region gender
            bool fillGender = false;
            string gender = "";
            if (rbtnMale1.IsChecked == true)
            {
                gender = "Male";
                fillGender = true;
            }
            else if (rbtnFemale1.IsChecked == true)
            {
                gender = "Female";
                fillGender = true;
            }
            //else
            //{
            //    //prompt user to select a gender
            //    MessageBox.Show("Fill in the mandatory fields.");
            //}
            #endregion

            #region email
            bool fillEmail = false;
            if (tbxEmail1.Text != "")
            {
                if (IsValidEmail(tbxEmail1.Text))
                {
                    fillEmail = true;
                }
                //else
                //{
                //    tbxEmail1.Text = "";
                //    MessageBox.Show("Enter a valid email address.");
                //}
            }
            #endregion

            bool fillFirstName = false;
            if (tbxFirstName1.Text != "")
            {
                if (tbxFirstName1.Text.Length < 20)
                {
                    fillFirstName = true;
                }
            }

            bool fillLastName = false;
            if (tbxLastName1.Text != "")
            {
                if (tbxLastName1.Text.Length < 49)
                {
                    fillLastName = true;
                }
            }

            bool fillAddress = false;
            if (tbxAddress3.Text != "")
            {
                if (tbxAddress3.Text.Length < 49)
                {
                    fillAddress = true;
                }
            }

            #region Postal Code, TelNum, MobNum --> checkNum
            double Num;
            bool fillPostalCode = false;
            if (double.TryParse(tbxPostalCode.Text, out Num))
            {
                if (tbxPostalCode.Text.Length == 6)
                {
                    fillPostalCode = true;
                }
                //else
                //{
                //    MessageBox.Show("Please enter a 6 digit Postal Code.");
                //}
            }

            bool fillTelNum = false;

            if (double.TryParse(tbxTelNum1.Text, out Num))
            {
                if (tbxTelNum1.Text.Length == 8)
                {
                    fillTelNum = true;
                }
                //else
                //{
                //    MessageBox.Show("Please enter a 8 digit Tel No.");
                //}
            }

            bool fillMobNum = false;
            if (double.TryParse(tbxMobNum1.Text, out Num))
            {
                if (tbxMobNum1.Text.Length == 8)
                {
                    fillMobNum = true;
                }
                //else
                //{
                //    MessageBox.Show("Please enter a 8 digit Mobile No.");
                //}
            }
            #endregion

            bool fillID = false;
            if (tbxIDNum1.Text != "")
            {
                if (tbxIDNum1.Text.Length == 9)
                {
                    if (NRICValidation(tbxIDNum1.Text))
                    {
                        fillID = true;
                    }
                    else
                    {
                        //Invalid NRIC format
                    }
                }
                else
                {
                    //Invalid Length of NRIC
                }
            }

            #region date
            bool fillDate = false;
            DateTime selectedTime = Convert.ToDateTime(dtpBirthDate1.SelectedDate);
            int result = DateTime.Compare(selectedTime, DateTime.Now);
            if (result < 0)
            {
                fillDate = true;
            }
            //else if (result > 0)
            //{
            //    MessageBox.Show("Date of Birth cannot be later than today.");
            //}

            bool fillAdminDate = false;
            DateTime selectedAdminDate = Convert.ToDateTime(dtpAdmissionDate.SelectedDate);
            int result2 = DateTime.Compare(selectedAdminDate, DateTime.Now);
            if (result < 0)
            {
                fillAdminDate = true;
            }
            #endregion

            if (fillAddress == true && fillDate == true && fillAdminDate == true && fillEmail == true && fillFirstName == true && fillGender == true && fillID == true && fillLastName == true && fillMobNum == true && fillPostalCode == true && fillTelNum == true)
            {
                grid_loading.Visibility = Visibility.Visible;
                svc.updatePatientCompleted += new EventHandler<tara_wcf.updatePatientCompletedEventArgs>(svc_updatePatientCompleted);
                svc.updatePatientAsync(patientDetail.Uid, tbxLastName1.Text, tbxFirstName1.Text, Convert.ToDateTime(dtpBirthDate1.SelectedDate), gender, tbxAddress3.Text, tbxPostalCode.Text, tbxTelNum1.Text, tbxMobNum1.Text, tbxEmail1.Text, imgName, tbxIDNum1.Text, Convert.ToDateTime(dtpAdmissionDate.SelectedDate));
                tara_wcf.patient patient = new tara_wcf.patient();
                patient.Uid = patientDetail.Uid;
                patient.LastName = tbxLastName1.Text;
                patient.FirstName = tbxFirstName1.Text;
                patient.Gender = gender;
                patient.DateOfBirth = Convert.ToDateTime(dtpBirthDate1.SelectedDate);
                patient.Address1 = tbxAddress3.Text;
                patient.Postcode = tbxPostalCode.Text;
                patient.ContactNumHome = tbxTelNum1.Text;
                patient.ContactNumMob = tbxMobNum1.Text;
                patient.Email = tbxEmail1.Text;
                patient.AdminDate = Convert.ToDateTime(dtpAdmissionDate.SelectedDate);
                patient.Nric = tbxIDNum1.Text;
                patient.ImageByte = imageByte;
                byte[] newImage;
                foreach (tara_wcf.patient p in PatientSelectionPage.patientList)
                {
                    if (p.Uid == patientDetail.Uid)
                    {
                        if (imageByte == null)
                        {
                            newImage = p.ImageByte;

                            PatientSelectionPage.patientList.Remove(p);
                            patient.ImageByte = newImage;
                            PatientSelectionPage.patientList.Add(patient);
                            break;
                        }
                        else
                        {
                            PatientSelectionPage.patientList.Remove(p);
                            PatientSelectionPage.patientList.Add(patient);
                            break;
                        }
                    }
                }
                //PatientSelectionPage.patientList.Add(patient);
            }
            else
            {
                MessageBox.Show("Updating of patient unsucessfully. Please ensure all required fields are entered");
            }
        }

        void svc_updatePatientCompleted(object sender, tara_wcf.updatePatientCompletedEventArgs e)
        {
            if (e.Result != null && e.Error == null)
            {
                bool add = e.Result;
                if (add == true)
                {
                    //MessageBox.Show("Updated Successfully.");
                    PatientSelectionPage.editted = true;
                    NavigationService.GoBack();
                }
                else
                {
                    grid_loading.Visibility = Visibility.Collapsed;
                    MessageBox.Show("Updating Failed. Please check connection.");
                }
            }
            else
            {
                grid_loading.Visibility = Visibility.Collapsed;
                MessageBox.Show("Update fail. Please retry again");
            }
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            grid_loading.Visibility = Visibility.Visible;
            svc.retrieveAllOwnPatientsCompleted += new EventHandler<tara_wcf.retrieveAllOwnPatientsCompletedEventArgs>(svc_retrieveAllOwnPatientsCompleted);
            svc.retrieveAllOwnPatientsAsync(LoginPage.doc.Uid);
        }

        void svc_retrieveAllOwnPatientsCompleted(object sender, tara_wcf.retrieveAllOwnPatientsCompletedEventArgs e)
        {
            PatientSelectionPage.patientList.Clear();
            PatientSelectionPage.patientList = e.Result;
            PatientSelectionPage.editted = true;
            NavigationService.GoBack();
        }

        private void btnLogout_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            NavigationService.Navigate(new LoginPage());
        }

        #region browse upload and convert image to byte

        string fileName;
        long fileSize;
        byte[] imageByte;
        private void btnBrowse1_Click(object sender, RoutedEventArgs e)
        {
            // Configure open file dialog box
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.FileName = "Image"; // Default file name
            dlg.DefaultExt = ".png"; // Default file extension
            dlg.Filter = "Image (.png)|*.png"; // Filter files by extension

            // Show open file dialog box
            Nullable<bool> result = dlg.ShowDialog();

            // Process open file dialog box results
            if (result == true)
            {
                // Open document
                fileName = dlg.FileName;

                FileInfo f = new FileInfo(fileName);
                fileSize = f.Length;

                imgProfilePicture1.Source = new BitmapImage(new Uri(@fileName));
                imageByte = ReadImageFile(fileName);
                imgName = upload(imageByte);
            }
        }

        public static byte[] ReadImageFile(string PostedFileName)
        {
            try
            {
                FileStream fs = new FileStream(PostedFileName, FileMode.Open, FileAccess.Read);

                BinaryReader br = new BinaryReader(fs);

                byte[] image = br.ReadBytes((int)fs.Length);

                br.Close();

                fs.Close();

                return image;
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }
        #endregion

        public static bool IsValidEmail(string strIn)
        {
            // Return true if strIn is in valid e-mail format.
            return Regex.IsMatch(strIn,
                   @"^(?("")("".+?""@)|(([0-9a-zA-Z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-zA-Z])@))" +
                   @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,6}))$");
        }

        BitmapSource LoadImage(Byte[] imageData)
        {
            using (MemoryStream ms = new MemoryStream(imageData))
            {
                var decoder = BitmapDecoder.Create(ms,
                    BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
                return decoder.Frames[0];
            }
        }

        private bool NRICValidation(string nric)
        {
            nric = nric.ToUpper();
            int first = nric[0];
            int second = nric[1];
            int third = nric[2];
            int fourth = nric[3];
            int fifth = nric[4];
            int sixth = nric[5];
            int seventh = nric[6];
            int eighth = nric[7];
            int nineth = nric[8];

            int sum = Convert.ToInt16(second - '0') * 2 + Convert.ToInt16(third - '0') * 7 + Convert.ToInt16(fourth - '0') * 6 + Convert.ToInt16(fifth - '0') * 5 + Convert.ToInt16(sixth - '0') * 4 + Convert.ToInt16(seventh - '0') * 3 + Convert.ToInt16(eighth - '0') * 2;
            int reminder = sum % 11;
            if (first.Equals('S') || first.Equals('T'))
            {
                switch (reminder)
                {
                    case 0:
                        if (nineth.Equals('J'))
                        {
                            return true;
                        }
                        break;
                    case 1:
                        if (nineth.Equals('Z'))
                        {
                            return true;
                        }
                        break;
                    case 2:
                        if (nineth.Equals('I'))
                        {
                            return true;
                        }
                        break;
                    case 3:
                        if (nineth.Equals('H'))
                        {
                            return true;
                        }
                        break;
                    case 4:
                        if (nineth.Equals('G'))
                        {
                            return true;
                        }
                        break;
                    case 5:
                        if (nineth.Equals('F'))
                        {
                            return true;
                        }
                        break;
                    case 6:
                        if (nineth.Equals('E'))
                        {
                            return true;
                        }
                        break;
                    case 7:
                        if (nineth.Equals('D'))
                        {
                            return true;
                        }
                        break;
                    case 8:
                        if (nineth.Equals('C'))
                        {
                            return true;
                        }
                        break;
                    case 9:
                        if (nineth.Equals('B'))
                        {
                            return true;
                        }
                        break;
                    case 10:
                        if (nineth.Equals('A'))
                        {
                            return true;
                        }
                        break;
                }
            }
            else if (first.Equals('F') || first.Equals('G'))
            {
                sum += 4;
                reminder = sum % 11;
                switch (reminder)
                {
                    case 0:
                        if (nineth.Equals('X'))
                        {
                            return true;
                        }
                        break;
                    case 1:
                        if (nineth.Equals('W'))
                        {
                            return true;
                        }
                        break;
                    case 2:
                        if (nineth.Equals('U'))
                        {
                            return true;
                        }
                        break;
                    case 3:
                        if (nineth.Equals('T'))
                        {
                            return true;
                        }
                        break;
                    case 4:
                        if (nineth.Equals('R'))
                        {
                            return true;
                        }
                        break;
                    case 5:
                        if (nineth.Equals('Q'))
                        {
                            return true;
                        }
                        break;
                    case 6:
                        if (nineth.Equals('P'))
                        {
                            return true;
                        }
                        break;
                    case 7:
                        if (nineth.Equals('N'))
                        {
                            return true;
                        }
                        break;
                    case 8:
                        if (nineth.Equals('M'))
                        {
                            return true;
                        }
                        break;
                    case 9:
                        if (nineth.Equals('L'))
                        {
                            return true;
                        }
                        break;
                    case 10:
                        if (nineth.Equals('K'))
                        {
                            return true;
                        }
                        break;
                }
            }
            return false;
        }

        public string upload(byte[] fileBytes)
        {
            string fileName = System.IO.Path.GetRandomFileName();
            fileName = fileName.Replace(".", "");
            fileName += ".png";
            bool result = false;
            try
            {
                CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
                {
                    configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));
                });
                //CloudStorageAccount cloudStorageAccount = CloudStorageAccount
                // Get the storage account reference
                CloudStorageAccount objStorage = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=tarastorage;AccountKey=GOu+LJLRqTxq7P0ZH89oNGYJFYmLkvayfJwIbINXI8cyv+q079VKOg4FS1ZSZuZJk/eAq8K81t8k2KVJ3b71EQ==");
                // get the Client reference using storage blobend point
                CloudBlobClient objClient = new CloudBlobClient(objStorage.BlobEndpoint, objStorage.Credentials);
                // Get Container reference
                // If i set to face, i can't retrieve it T>T
                //CloudBlobContainer objContainer = objClient.GetContainerReference("face");
                CloudBlobContainer objContainer = objClient.GetContainerReference("tarastorage");
                // Get blob reference
                CloudBlob obj = objContainer.GetBlobReference(fileName);
                // Set meta values
                obj.Metadata["MetaName"] = "meta";
                // Open a stream using the cloud object
                BlobStream blobstream = obj.OpenWrite();
                // Write the stream to the blob database
                blobstream.Write(imageByte, 0, imageByte.Count());
                blobstream.Close();
                result = true;
                fillFile = true;
            }
            catch (Exception)
            {
                result = false;
            }
            return result == true ? "http://tarastorage.blob.core.windows.net/tarastorage/" + fileName : String.Empty;
        }
    }
}